﻿using AwesomeChromeFormUI.Cache;
using AwesomeChromeFormUI.ChromiumForms;
using AwesomeChromeFormUI.Interfaces;
using AwesomeChromeFormUI.Interfaces.Implements;
using AwesomeChromeFormUI.Utils;
using CefSharp;
using System;
using System.Windows.Forms;

namespace AwesomeChromeFormUI.App
{
    /// <summary>
    /// Cef 应用抽象类
    /// </summary>
    public abstract class CefApp : IDisposable
    {
        protected CefApp()
        {
            
        }

        /// <summary>
        /// 主窗口
        /// </summary>
        private IMainView _mainView;

        protected IMainView MainView { get { return _mainView; } }

        /// <summary>
        /// 释放非托管资源
        /// </summary>
        public void Dispose()
        {
            GC.SuppressFinalize(this);
        }
        /// <summary>
        /// 初始化
        /// </summary>
        protected abstract void PlatformInitialize();
        /// <summary>
        /// 主循环
        /// </summary>
        protected abstract void PlatformRunMessageLoop();
        /// <summary>
        /// 关闭
        /// </summary>
        protected abstract void PlatformShutdown();
        /// <summary>
        /// 退出
        /// </summary>
        protected abstract void PlatformQuitMessageLoop();
        /// <summary>
        /// 创建主窗口
        /// </summary>
        /// <returns></returns>
        protected abstract IMainView CreateMainView();

        public void Quit()
        {
            PlatformQuitMessageLoop();
        }

        /// <summary>
        /// 运行入口
        /// </summary>
        /// <returns></returns>
        public int Run(string[] args)
        {
            // 解析 args
            // TODO 
            // 运行内部方法
            return RunInternal(true);
        }

        /// <summary>
        /// Run 内部运行逻辑
        /// </summary>
        /// <param name="isConcurrentTaskExecution"></param>
        /// <returns></returns>
        private int RunInternal(bool isConcurrentTaskExecution)
        {

            // We're going to manually call Cef.Shutdown below, this maybe required in some complex scenarios
            CefSharpSettings.ShutdownOnExit = false;

            // 允许 JS 调用 Task<T> 类型返回值的方法
            CefSharpSettings.ConcurrentTaskExecution = isConcurrentTaskExecution;

            // 初始化 CEF
            IConfigurationExecuter executer = new CefConfigurationExecuter();
            executer.Execute();

            // 初始化应用
            PlatformInitialize();

            // 创建主窗口
            this._mainView = CreateMainView();

            Form currentForm = MainViewUtil.GetCurrentForm();
            string handle = currentForm.Handle.ToString();

            // 全局缓存
            GlobalBrowserCache.Cache.Add(handle, this._mainView.CurrentBrowser);

            // 应用运行主循环
            PlatformRunMessageLoop();

            // 释放主窗口资源
            this._mainView.Dispose();

            this._mainView = null;

            // 移除缓存
            GlobalBrowserCache.Cache.Remove(handle);

            // Shutdown before your application exists or it will hang.
            Cef.Shutdown();

            // 关闭应用
            PlatformShutdown();

            return 0;
        }
    }
}
